﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

internal class MonitorInfo
{
    public string DisplayName;
    public string DisplayId;
    public bool IsPrimary;
    public int X;
    public int Y;
    public int Width;
    public int Height;
    public int DpiValue;
    public bool IsTouchDisplay;
}

internal class Program
{
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    private struct DISPLAY_DEVICE
    {
        public int cb;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
        public string DeviceName;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string DeviceString;

        public int StateFlags;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string DeviceID;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
        public string DeviceKey;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    private struct DEVMODE
    {
        private const int CCHDEVICENAME = 32;
        private const int CCHFORMNAME = 32;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHDEVICENAME)]
        public string dmDeviceName;

        public ushort dmSpecVersion;
        public ushort dmDriverVersion;
        public ushort dmSize;
        public ushort dmDriverExtra;
        public uint dmFields;
        public int dmPositionX;
        public int dmPositionY;
        public uint dmDisplayOrientation;
        public uint dmDisplayFixedOutput;
        public short dmColor;
        public short dmDuplex;
        public short dmYResolution;
        public short dmTTOption;
        public short dmCollate;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCHFORMNAME)]
        public string dmFormName;

        public ushort dmLogPixels;
        public uint dmBitsPerPel;
        public uint dmPelsWidth;
        public uint dmPelsHeight;
        public uint dmDisplayFlags;
        public uint dmDisplayFrequency;
        public uint dmICMMethod;
        public uint dmICMIntent;
        public uint dmMediaType;
        public uint dmDitherType;
        public uint dmReserved1;
        public uint dmReserved2;
        public uint dmPanningWidth;
        public uint dmPanningHeight;
    }

    private const int EDD_GET_DEVICE_INTERFACE_NAME = 0x00000001;
    private const int ENUM_CURRENT_SETTINGS = -1;
    private const int DISPLAY_DEVICE_ATTACHED_TO_DESKTOP = 0x00000001;
    private const int DISPLAY_DEVICE_PRIMARY_DEVICE = 0x00000004;

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    private static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);

    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    private static extern bool EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE devMode);

    private static void Main()
    {
        List<MonitorInfo> monitors = new List<MonitorInfo>();
        int primaryIndex = -1;
        uint devId = 0;

        while (true)
        {
            DISPLAY_DEVICE displayDevice = new DISPLAY_DEVICE();
            displayDevice.cb = Marshal.SizeOf(displayDevice);
            if (!EnumDisplayDevices(null, devId, ref displayDevice, 0))
                break;

            // Skip disconnected
            if ((displayDevice.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP) == 0)
            {
                devId++;
                continue;
            }

            bool isPrimary = (displayDevice.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) != 0;

            MonitorInfo monitor = new MonitorInfo();
            monitor.IsPrimary = isPrimary;
            monitor.DisplayName = displayDevice.DeviceString;

            // Get device ID (like \\.\DISPLAY1)
            string deviceId = displayDevice.DeviceName;

            // Get interface path (optionally, same as C++中EnumDisplayDevices第二次调用)
            DISPLAY_DEVICE displayDevice2 = new DISPLAY_DEVICE();
            displayDevice2.cb = Marshal.SizeOf(displayDevice2);
            if (EnumDisplayDevices(deviceId, 0, ref displayDevice2, EDD_GET_DEVICE_INTERFACE_NAME))
            {
                monitor.DisplayId = displayDevice2.DeviceID;
            }
            else
            {
                monitor.DisplayId = deviceId;
            }

            // Get DEVMODE
            DEVMODE devmode = new DEVMODE();
            devmode.dmSize = (ushort)Marshal.SizeOf(typeof(DEVMODE));
            if (EnumDisplaySettings(deviceId, ENUM_CURRENT_SETTINGS, ref devmode))
            {
                monitor.X = devmode.dmPositionX;
                monitor.Y = devmode.dmPositionY;
                monitor.Width = (int)devmode.dmPelsWidth;
                monitor.Height = (int)devmode.dmPelsHeight;
            }

            // TODO: 替代 RoomsDpiHelper::GetDPIValue(deviceId)
            monitor.DpiValue = 96; // 默认值

            // TODO: 替代 isTouchDisplays(deviceId)
            monitor.IsTouchDisplay = false;

            if (isPrimary)
                primaryIndex = monitors.Count;

            monitors.Add(monitor);
            devId++;
        }

        // 控制最大显示器数量（可选逻辑）
        int maxCount = 3; // 举例
        while (monitors.Count > maxCount)
        {
            if (primaryIndex != 0)
            {
                monitors.RemoveAt(0);
                primaryIndex--;
            }
            else
            {
                monitors.RemoveAt(monitors.Count - 1);
            }
        }

        // 输出
        for (int i = 0; i < monitors.Count; i++)
        {
            var m = monitors[i];
            Console.WriteLine($"Monitor {i + 1}: {m.DisplayName}, {m.DisplayId}, Primary: {m.IsPrimary}, Pos: ({m.X},{m.Y}), Size: {m.Width}x{m.Height}, DPI: {m.DpiValue}");
        }

        // 逻辑判断模型
        if (monitors.Count > 1)
        {
            Console.WriteLine("设置为 NORMAL_MODEL（多屏）");
        }
        else
        {
            Console.WriteLine("移除 DeviceLimit 配置（单屏）");
        }

        Console.ReadLine();
    }
}